home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1994 / MacHack 1994.toast / MacHack™ 1987-1994 / MacHack™ '91 / '91 Attendee Contributions / Rotate Src / rotate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-20  |  10.5 KB  |  453 lines  |  [TEXT/MPS ]

  1. /* Rotate.c is the Macintosh shell for the Rotate.a algorithms */
  2.  
  3. #include    <Quickdraw.h>
  4. #include    <Desk.h>
  5. #include    <Dialogs.h>
  6. #include    <Events.h>
  7. #include    <Fonts.h>
  8. #include    <Memory.h>
  9. #include    <Menus.h>
  10. #include    <OSEvents.h>
  11. #include    <Packages.h>
  12. #include    <Resources.h>
  13. #include    <SegLoad.h>
  14. #include    <Toolutils.h>
  15. #include    <Windows.h>
  16. #include     "Rotate.h"
  17.  
  18. typedef enum {Rot0, RotH, RotV, RotX,
  19.               RotL, RotR, RotFL, RotFR} RotationSw;
  20.  
  21. pascal void ROTATE(rotation, sourceMap, destMap)
  22. RotationSw rotation;
  23. BitMap *sourceMap, *destMap;
  24. extern;
  25.  
  26. /*    Global Data objects, used by routines external to main(). */
  27. Boolean         doneFlag;        /* Becomes TRUE when File/Quit chosen */
  28. WindowRecord    wRecord;
  29. WindowPtr        myWindow;        /* Referenced often */
  30. EventRecord     myEvent;
  31. WindowPtr        whichWindow;
  32. long            lastTick,tick;
  33. long            stretch ;         /* used to vary the bounds of the Pict */
  34.  
  35. /*******************************/
  36. /*    BitMap Image Declarations  */
  37. /*******************************/
  38.  
  39. #define    xInset        10
  40. #define    yInset        20
  41.  
  42. #define    MyLeft          0
  43. #define    MyRight        ((kWindowWidth - 3*xInset) / 2)
  44. #define    MyTop          0
  45. #define    MyBottom    MyRight
  46.  
  47. #define    leftInset    xInset
  48. #define    rightInset    (kWindowWidth - (MyRight - MyLeft) - xInset)
  49. BitMap sourceMap, destMap;
  50.  
  51. /***************************/
  52. /*    BitMap Image Routines  */
  53. /***************************/
  54.  
  55. InitImage(Image)
  56. BitMap *Image;
  57. {
  58.     int    myRowBytes  = ((MyRight - MyLeft + 15) / 16) * 2;
  59.     int    mySize        = myRowBytes * (MyBottom - MyTop);
  60.     
  61.     Image->baseAddr = NewPtr(mySize);    /* allocate memory */
  62.     Image->rowBytes = myRowBytes;
  63.     SetRect(&Image->bounds, MyLeft, MyTop, MyRight, MyBottom);
  64. }
  65.  
  66. BuildImage(Image)
  67. BitMap *Image;
  68. {                            /* Create an Image to rotate  */
  69.     GrafPort myPort,*savePort;
  70.  
  71.     GetPort(&savePort);
  72.     OpenPort(&myPort);
  73.     SetPortBits(Image);
  74.     RectRgn(myPort.visRgn, &Image->bounds);
  75.     PortSize(Image->bounds.right, Image->bounds.bottom);
  76.     SetPort(savePort);
  77.     ClosePort(&myPort);
  78. }
  79.  
  80. ShowImage(Image,myXoff,myYoff)
  81. BitMap *Image;
  82. short myXoff,myYoff;
  83. {
  84.     GrafPtr myPort;    
  85.  
  86.     GetPort(&myPort);
  87.     OffsetRect(&Image->bounds, myXoff,  myYoff);    
  88.     CopyBits(Image, &myPort->portBits, &Image->bounds, &Image->bounds, srcXor, 0L);     
  89.     OffsetRect(&Image->bounds, -myXoff, -myYoff);
  90. }
  91. typedef enum {Rot0, RotH, RotV, RotX,
  92.               RotL, RotR, RotFL, RotFR} RotationSw;
  93.  
  94. RotateBox(rotation, portRect, sourceRect, destRect)
  95. RotationSw rotation;
  96. Rect *portRect, *sourceRect, *destRect;
  97. {
  98.     *destRect = *sourceRect;
  99.     switch (rotation) {
  100.     case Rot0:
  101.         break;
  102.     case RotH:
  103.         destRect->right = portRect->right - destRect->left;
  104.         destRect->left = portRect->left - destRect->right;
  105.         break;
  106.     case RotV:
  107.         destRect->top = portRect->top - destRect->bottom;    /** ?? **/
  108.         destRect->bottom = portRect->bottom - destRect->top;
  109.         break;
  110.     case RotX:
  111.         destRect->top = portRect->top - destRect->bottom;
  112.         destRect->bottom = portRect->bottom - destRect->top;
  113.         destRect->right = portRect->right - destRect->left;
  114.         destRect->left = portRect->left - destRect->right;
  115.         break;
  116.     case RotL:
  117.         destRect->left = portRect->left + (destRect->top - portRect->top);
  118.         destRect->right = destRect->left + (destRect->bottom - destRect->top);
  119.         destRect->top = portRect->top + (portRect->right - destRect->right);    /** ?? **/
  120.         break;
  121.     case RotR:
  122.         break;
  123.     case RotFL:
  124.         break;
  125.     case RotFR:
  126.         break;
  127.     }
  128. }
  129.  
  130. RotateImage(rotation, sourceMap, destMap)
  131. RotationSw rotation;
  132. BitMap *sourceMap, *destMap;
  133. {
  134.     int    size;
  135.     Rect r;
  136.  
  137.     if (destMap->baseAddr) {                    /* If there an old image */
  138.         ShowImage(destMap, rightInset, yInset);    /* Display image to erase it */
  139.         DisposPtr(destMap->baseAddr);            /*  then, free it */
  140.         destMap->baseAddr = 0;
  141.     }
  142.     if ((rotation == RotL) && (rotation == RotR) && 
  143.         (rotation == RotFL) && (rotation == RotFR)) {
  144.         r.top = sourceMap->bounds.left;
  145.         r.bottom = sourceMap->bounds.right;
  146.         r.left = sourceMap->bounds.top;
  147.         r.right = sourceMap->bounds.bottom;
  148.     } else
  149.         r = sourceMap->bounds;
  150.     destMap->bounds = r;
  151.     destMap->rowBytes = ((destMap->bounds.right - destMap->bounds.left + 15) >> 4) << 1;
  152.     size = destMap->rowBytes * (destMap->bounds.bottom - destMap->bounds.top);
  153.     destMap->baseAddr = NewPtr(size+20);
  154.     WaitForTick();                                /* wait for the clock to tick */
  155.     ROTATE(rotation, sourceMap, destMap);        /* Do the rotation */
  156.     ShowTick(rotation);                            /* Time it */
  157.     ShowImage(destMap, rightInset, yInset);        /* Display the rotated image */
  158. }
  159.  
  160. GarbageImage(Image)
  161. BitMap *Image;
  162. {
  163.     int    size = Image->rowBytes * (Image->bounds.bottom - Image->bounds.top);
  164.     char *p = Image->baseAddr;
  165.     char *g = 100;            /* just some low memory address */
  166.     
  167.     ShowImage(Image, leftInset, yInset);    /* Display image to erase it */
  168.     while (size--)
  169.         *p++ = *g++;
  170.     ShowImage(Image, leftInset, yInset);    /* Display Image */
  171. }
  172.  
  173. FillImage(Image, color)
  174. BitMap *Image;
  175. int color;
  176. {
  177.     int    size = Image->rowBytes * (Image->bounds.bottom - Image->bounds.top);
  178.     char *p = Image->baseAddr;
  179.     
  180.     ShowImage(Image, leftInset, yInset);    /* Display image to erase it */
  181.     while (size--)
  182.         *p++ = color;
  183.     ShowImage(Image, leftInset, yInset);    /* Display Image */
  184. }
  185.  
  186. GetPict(Image)
  187. BitMap *Image;
  188. {
  189.     int refNum, picWidth, picHeight;
  190.     GrafPort myPort,*savePort;
  191.     PicHandle srcPict;
  192.     Rect *irp;
  193.  
  194.     if (Image->baseAddr) {                /* If there an old image */
  195.         ShowImage(Image, leftInset, yInset); /* Display image to erase it */
  196.         DisposPtr(Image->baseAddr);        /*    then, free it */
  197.         Image->baseAddr = 0;
  198.     }
  199. /* Load the PICT, compute target Rect to center in image window, draw it */
  200.     refNum = OpenResFile("\pBell");
  201.     srcPict = (PicHandle)GetResource('PICT', rBell); /* load PICT resource    */
  202.     if (srcPict == 0L) {
  203.         doAlert(rAlert,kNoBell);
  204.         ExitToShell();
  205.     }
  206.     HLock((Handle)srcPict);
  207.     irp = &((*srcPict)->picFrame);            /* pointer to PICT's bounds    */
  208.     picWidth = scale*(irp->right - irp->left);    /* compute PICT width        */
  209.     picHeight = scale*(irp->bottom - irp->top);    /* compute PICT height        */
  210.  
  211.     picWidth += stretch;
  212.     picHeight += stretch;
  213.  
  214.     Image->bounds.left = 0;                    /* PICT size Rect    */
  215.     Image->bounds.top = 0;
  216.     Image->bounds.right = Image->bounds.left + picWidth;
  217.     Image->bounds.bottom = Image->bounds.top + picHeight;
  218.     Image->rowBytes = ((picWidth + 15) / 16) * 2;
  219.     Image->baseAddr = NewPtr(Image->rowBytes * Image->bounds.bottom);
  220.  
  221.     GetPort(&savePort);
  222.     OpenPort(&myPort);
  223.     SetPortBits(Image);
  224.     RectRgn(myPort.visRgn, &Image->bounds);
  225.     PortSize(Image->bounds.right, Image->bounds.bottom);
  226.     DrawPicture(srcPict,&Image->bounds);
  227.     FrameRect(&Image->bounds);
  228.     SetPort(savePort);
  229.     ClosePort(&myPort);
  230.  
  231.     HUnlock((Handle)srcPict);             /* we no longer need resource */
  232.     CloseResFile(refNum);
  233.     ShowImage(Image, leftInset, yInset); /* Display sourceMap */
  234. }
  235.  
  236. /******************************/
  237. /*    Low level system routines */
  238. /******************************/
  239.  
  240. doAlert(theAlert,theInx)
  241. short theAlert,theInx;
  242. {
  243.     Str255 theText;
  244.  
  245.     GetIndString(theText,rTextStr,theInx);
  246.     SysBeep(4);
  247.     ParamText(theText,0,0,0);
  248.     Alert(theAlert,0);
  249. }
  250.  
  251. WaitForTick()
  252. {
  253.     tick = TickCount();
  254.     while (tick == TickCount())
  255.         ;    /* wait */
  256.     lastTick = tick;
  257. }
  258.  
  259. ShowNum(n,x,y)
  260. int n,x,y;
  261. {
  262.     Rect r;
  263.     Str255 myStr;
  264.  
  265.     NumToString(n, myStr);
  266.     SetRect(&r, x, y-10, x+40, y+2);
  267.     EraseRect(&r);
  268.     MoveTo(x,y);
  269.     DrawString(myStr);
  270. }
  271.  
  272. ShowTick(rotation)
  273. RotationSw rotation;
  274. {
  275.     int n,x,y;
  276.     
  277.     n = TickCount() - lastTick;
  278.     x = 160 + 40 * rotation;
  279.     y = 3*yInset + MyBottom;
  280.     MoveTo(90,y);
  281.     DrawString("\p Ticks = ");
  282.     ShowNum(n, x, y);
  283. }
  284.  
  285. ShowSize(sourceMap)
  286. BitMap *sourceMap;
  287. {
  288.     int x,y;
  289.     
  290.     x = 160;
  291.     y = 2*yInset + MyBottom;
  292.     MoveTo(90,y);
  293.     DrawString("\pBounds = ");
  294.     ShowNum(sourceMap->bounds.left, x, y);
  295.     x += 40;
  296.     ShowNum(sourceMap->bounds.top, x, y);
  297.     x += 40;
  298.     ShowNum(sourceMap->bounds.right, x, y);
  299.     x += 40;
  300.     ShowNum(sourceMap->bounds.bottom, x, y);
  301. }
  302.  
  303.  
  304. /****************************/
  305. /*    Event handling routines */
  306. /****************************/
  307.  
  308. doEvent()
  309. {
  310.     SystemTask();
  311.  
  312.     if (GetNextEvent(everyEvent, &myEvent))
  313.     switch (myEvent.what) {
  314.         case mouseDown:
  315.             switch (FindWindow(myEvent.where, &whichWindow)) {
  316.                 case inSysWindow:
  317.                     SystemClick(&myEvent, whichWindow);
  318.                     break;
  319.                 case inMenuBar:
  320.                     doCommand(MenuSelect(myEvent.where));
  321.                     break;
  322.                 case inContent:
  323.                     if (whichWindow != FrontWindow())
  324.                         SelectWindow(whichWindow);
  325.                     break;
  326.             }
  327.             break;
  328.     
  329.         case keyDown:
  330.         case autoKey:
  331.             if (myWindow == FrontWindow()) {
  332.                 if (myEvent.modifiers & cmdKey) {
  333.                     doCommand(MenuKey(myEvent.message & charCodeMask));
  334.                 }
  335.             }
  336.             break;
  337.     
  338.         case updateEvt:
  339.             if ((WindowPtr) myEvent.message == myWindow) {
  340.                 BeginUpdate(myWindow);
  341.                 EraseRect(&myWindow->portRect);
  342.                 ShowImage(&sourceMap, leftInset, yInset);/* Display image */
  343.                 ShowImage(&destMap, rightInset, yInset); /* Display destMap */
  344.                 ShowSize(&sourceMap);
  345.                 EndUpdate(myWindow);
  346.             }
  347.             break;
  348.     }
  349. }
  350.  
  351. setupMenus()
  352. {
  353.     Handle menuBar;
  354.  
  355.     menuBar = GetNewMBar(rMenuBar);            /* read menus into menu bar */
  356.     if (menuBar == nil) ExitToShell();
  357.     SetMenuBar(menuBar);                    /* install menus */
  358.     AddResMenu(GetMHandle(mApple), 'DRVR');    /* add DA names to Apple menu */
  359.     DrawMenuBar();
  360. }
  361.  
  362. NewScreen()
  363. {
  364.     myWindow = GetNewWindow(rWindow, nil, (WindowPtr) -1);
  365.     SetPort(myWindow);
  366. }
  367.  
  368. /* Process mouse clicks in menu bar */
  369. doCommand(mResult)
  370. long    mResult;
  371. {
  372.     short         theMenu, theItem;
  373.     char        daName[256];
  374.     GrafPtr     savePort;
  375.     RotationSw    rot;
  376.  
  377.     theMenu = HiWord(mResult);
  378.     theItem = LoWord(mResult);
  379.     switch (theMenu) {
  380.         case mApple:
  381.             if (theItem == aboutMeCommand)
  382.                 doAlert(rMsg,kAboutText);
  383.             else {
  384.                 GetItem(GetMHandle(mApple), theItem, daName);
  385.                 GetPort(&savePort);
  386.                 (void) OpenDeskAcc(daName);
  387.                 SetPort(savePort);
  388.             }
  389.             break;
  390.  
  391.         case mFile:
  392.             if (theItem == quitCommand)
  393.                 doneFlag = true;            /* Request exit */
  394.             break;
  395.  
  396.         case mImage:
  397.             switch (theItem) {
  398.             case GarbageCommand:
  399.                 GarbageImage(&sourceMap);
  400.                 break;
  401.             case BlackCommand:
  402.                 FillImage(&sourceMap, 0xFF);
  403.                 break;
  404.             case WhiteCommand:
  405.                 FillImage(&sourceMap, 0);
  406.                 break;
  407.             case BellCommand:
  408.                 stretch = 0;        /* reset stretch */
  409.                 GetPict(&sourceMap);
  410.                 break;
  411.             case StretchCommand:
  412.                 stretch++;
  413.                 GetPict(&sourceMap);
  414.                 break;
  415.             } /*endsw theItem*/
  416.             ShowSize(&sourceMap);    /* display the bounds */
  417.             break;
  418.  
  419.         case mRotate:
  420.             if (theItem == RotAllCommand) {
  421.                 for (rot=0; rot < 8; rot++)
  422.                     RotateImage(rot, &sourceMap, &destMap);
  423.             } else
  424.                 RotateImage(theItem - Rot0Command, &sourceMap, &destMap);
  425.             break;
  426.     }
  427.     HiliteMenu(0);
  428. }
  429.  
  430. main()
  431. {
  432.     MaxApplZone();
  433.     MoreMasters();
  434.  
  435. /*    Initialization traps    */
  436.     InitGraf(&qd.thePort);
  437.     InitFonts();
  438.     FlushEvents(everyEvent, 0);
  439.     InitWindows();
  440.     InitMenus();
  441.     TEInit();
  442.     InitDialogs(nil);
  443.     InitCursor();
  444.  
  445.     setupMenus();
  446.     doneFlag = false;
  447.     NewScreen();
  448.     InitImage(&sourceMap);
  449.     BuildImage(&sourceMap);
  450.     while (!doneFlag)
  451.         doEvent();
  452. }
  453.